﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RandomKeyGenerator
{

    /// <summary>
    /// A fabrica de chaves aleatorias possui um vetor de RandomKeys que possui o tamanho igual a N sendo n o numero de vertices do grafo.
    /// </summary>
    public class FabricaCromossomos
    {
        private Gene[] chaves;
        private int qtde_genes; //esta variavel irá guardar as chaves aleatórias responsáveis pela ordenação dos elementos
        

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="tamanho">O numero de nos do grafo</param>
        public FabricaCromossomos(int tamanhoOrdenacao)
        {
         
            this.qtde_genes = tamanhoOrdenacao;
            this.chaves = new Gene[this.qtde_genes];

        }

        public FabricaCromossomos():this(0)
        {

        }


        /// <summary>
        /// Inicializa o vetor de random Keys com numeros aleatorios.
        /// </summary>
        /// <returns>Vetor de random keys inicializado e ordenado</returns>
        public Gene[] GenerateRandomKeys()
        {
            this.chaves = new Gene[this.qtde_genes];


            for (int i = 0; i < this.qtde_genes; i++)
            {
                this.chaves[i] = new Gene();

                //eh importante guardar o indice inicial do alelo pois no nomento em que este for ordenado, conseguimos
                //a rastreabilidade do no nao eh perdida.
                this.chaves[i].Indice = i;

                this.chaves[i].KeyOrdenacao = Math.Round(RandomNumberGenerator.GenerateRandomNumber(), 2);
                this.chaves[i].KeyCriterio = Math.Round(RandomNumberGenerator.GenerateRandomNumber(), 2);
            }

            Array.Sort(this.chaves);

            return this.chaves;
        }
        

        /// <summary>
        /// Inicializa o vetor de random Keys com numeros aleatorios.
        /// </summary>
        /// <returns>Vetor de random keys inicializado e ordenado</returns>
        public Cromossomo GenerateRandomKeysWithValue()
        {
            Cromossomo rk = new Cromossomo();

            rk.Chaves = new Gene[this.qtde_genes];
            rk.Value = -1;


            for (int i = 0; i < this.qtde_genes; i++)
            {
                rk.Chaves[i] = new Gene();
                rk.Chaves[i].Indice = i;

                rk.Chaves[i].KeyOrdenacao = Math.Round(RandomNumberGenerator.GenerateRandomNumber(), 2);
                rk.Chaves[i].KeyCriterio = Math.Round(RandomNumberGenerator.GenerateRandomNumber(), 2);
            }

            return rk;
        }


        public int GenerateRandomNumberFromMax(int max)
        {
            if (max == 1)
                return 0;

            return RandomNumberGenerator.GenerateRandomNumberFromInterval(0, max);
        }

        public double GenerateRandomDoubleNumberFromInterval(int inicio, int fim)
        {
            double num = (double)RandomNumberGenerator.GenerateRandomNumberFromInterval(inicio, fim);

            num += this.RowBiasedDice();

            return num;
        }

        public double RowBiasedDice()
        {
            return RandomNumberGenerator.GenerateRandomNumber();
        }
    }
}
